﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LINQPad.Extensibility.DataContext;
using LINQPad.OpenAccess.Settings;

namespace LINQPad.OpenAccess.Services.Descriptors
{
    /// <summary>
    /// Abstract base class for <see cref="IConnectionDescriptor"/> implementations.
    /// </summary>
    public abstract class ConnectionDescriptorBase : IConnectionDescriptor
    {
        #region Protected

        #region - Functions

        /// <summary>
        /// Gets the context assembly path.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <returns>
        /// The path or <c>null</c>.
        /// </returns>
        protected string GetContextAssemblyPath( IConnectionInfo connectionInfo )
        {
            ICustomTypeInfo customTypeInfo;
            if ( connectionInfo != null
                    && null != ( customTypeInfo = connectionInfo.CustomTypeInfo ) )
                return customTypeInfo.CustomAssemblyPath;
            return null;
        }
        /// <summary>
        /// Gets the name of the context type.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <returns>
        /// The name of the context type or an empty string.
        /// </returns>
        protected string GetContextTypeName( IConnectionInfo connectionInfo )
        {
            string contextTypeName = null;
            ICustomTypeInfo customTypeInfo;
            if ( connectionInfo != null
                    && null != ( customTypeInfo = connectionInfo.CustomTypeInfo )
                    && !String.IsNullOrWhiteSpace( customTypeInfo.CustomTypeName ) )
            {
                var parts = customTypeInfo.CustomTypeName.Split( '.' );
                return parts[parts.Length - 1];
            }

            return contextTypeName ?? String.Empty;
        }
        #endregion

        #endregion

        #region Public

        #region - Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ConnectionDescriptorBase" /> class.
        /// </summary>
        /// <param name="priority">The priority.</param>
        public ConnectionDescriptorBase( int priority = 0 )
        {
            this.Priority = priority;
        }

        #endregion

        #endregion

        #region IConnectionDescriptor Members

        #region - Functions

        /// <summary>
        /// Determines whether this instance is able to describe the specified connection.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <param name="driverSettings">The driver settings.</param>
        /// <returns>
        ///   <c>true</c> if this instance is able to describe the specified connection; otherwise, <c>false</c>.
        /// </returns>
        public abstract bool CanDescribe( IConnectionInfo connectionInfo, DriverSettings driverSettings );
        /// <summary>
        /// Describes the specified connection.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <param name="driverSettings">The driver settings.</param>
        /// <returns>
        /// The description.
        /// </returns>
        public abstract string Describe( IConnectionInfo connectionInfo, DriverSettings driverSettings );

        #endregion

        #region - Properties

        /// <summary>
        /// Gets the priority of the descriptor.
        /// </summary>
        /// <value>
        /// The priority.
        /// </value>
        public int Priority
        {
            get;
            private set;
        }

        #endregion

        #endregion
    }
}
